/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Integration;

import MathLib.triangulation.SaveStructures.Node;

/**
 *
 * @author mark
 */
public class GaussQuadrature {
    protected double x[];
    protected double w[];
    protected int n;

    public GaussQuadrature(int n) {

        if((n!=5)&&(n!=20)&&(n!=40)&&(n!=50)&&((n!=100))){
            n=10;
        }
        this.n = n;
        x =  new double[n];
        w =  new double[n];
        if(n==5){
            x[0] = 0.0;
            x[1] = -Math.sqrt(245 - 14 * Math.sqrt(70)) / 21.0;
            x[2] = Math.sqrt(245 - 14 * Math.sqrt(70)) / 21.0;
            x[3] = -Math.sqrt(245 + 14 * Math.sqrt(70)) / 21.0;
            x[4] = Math.sqrt(245 + 14 * Math.sqrt(70)) / 21.0;

            w[0] = 128.0 / 225.0;
            w[1] = (322.0 + 13.0 * Math.sqrt(70)) / 900.0;
            w[2] = (322.0 + 13.0 * Math.sqrt(70)) / 900.0;
            w[3] = (322.0 - 13.0 * Math.sqrt(70)) / 900.0;
            w[4] = (322.0 - 13.0 * Math.sqrt(70)) / 900.0;
        }
        if(n==10){

            x[0] = -0.973906528517172;
            x[1] = -0.865063366688985;
            x[2] = -0.679409568299024;
            x[3] = -0.433395394129247;
            x[4] = -0.148874338981631;
            x[5] = 0.148874338981631;
            x[6] = 0.433395394129247;
            x[7] = 0.679409568299025;
            x[8] = 0.865063366688984;
            x[9] = 0.973906528517172;
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            w[0] = 0.0666713443086882;
            w[1] = 0.149451349150581;
            w[2] = 0.219086362515983;
            w[3] = 0.269266719309996;
            w[4] = 0.295524224714753;
            w[5] = 0.295524224714753;
            w[6] = 0.269266719309996;
            w[7] = 0.219086362515982;
            w[8] = 0.149451349150581;
            w[9] = 0.0666713443086877;
        }
        if(n==20){
            x[0] = -0.993128599185095;
            x[1] = -0.963971927277913;
            x[2] = -0.912234428251326;
            x[3] = -0.839116971822219;
            x[4] = -0.74633190646015;
            x[5] = -0.636053680726515;
            x[6] = -0.510867001950827;
            x[7] = -0.37370608871542;
            x[8] = -0.227785851141645;
            x[9] = -0.0765265211334973;
            x[10] = 0.0765265211334971;
            x[11] = 0.227785851141645;
            x[12] = 0.373706088715419;
            x[13] = 0.510867001950827;
            x[14] = 0.636053680726515;
            x[15] = 0.74633190646015;
            x[16] = 0.839116971822219;
            x[17] = 0.912234428251326;
            x[18] = 0.963971927277914;
            x[19] = 0.993128599185095;
        //++++++++++    +++++++++++++++++++++++++++++++++++++++++++++++++++++
            w[0] = 0.0176140071391524;
            w[1] = 0.0406014298003871;
            w[2] = 0.0626720483341091;
            w[3] = 0.0832767415767047;
            w[4] = 0.10193011981724;
            w[5] = 0.118194531961518;
            w[6] = 0.131688638449177;
            w[7] = 0.142096109318382;
            w[8] = 0.149172986472604;
            w[9] = 0.152753387130725;
            w[10] = 0.152753387130727;
            w[11] = 0.149172986472603;
            w[12] = 0.142096109318383;
            w[13] = 0.131688638449176;
            w[14] = 0.118194531961519;
            w[15] = 0.10193011981724;
            w[16] = 0.083276741576705;
            w[17] = 0.0626720483341087;
            w[18] = 0.0406014298003872;
            w[19] = 0.017614007139152;
        }

        if(n==40){
            x[0] = -0.998237709710559;
            x[1] = -0.990726238699457;
            x[2] = -0.977259949983774;
            x[3] = -0.957916819213792;
            x[4] = -0.932812808278677;
            x[5] = -0.902098806968874;
            x[6] = -0.865959503212259;
            x[7] = -0.824612230833311;
            x[8] = -0.778305651426519;
            x[9] = -0.727318255189927;
            x[10] = -0.671956684614179;
            x[11] = -0.61255388966798;
            x[12] = -0.549467125095128;
            x[13] = -0.483075801686179;
            x[14] = -0.413779204371605;
            x[15] = -0.341994090825759;
            x[16] = -0.268152185007254;
            x[17] = -0.192697580701371;
            x[18] = -0.116084070675255;
            x[19] = -0.0387724175060507;
            x[20] = 0.0387724175060509;
            x[21] = 0.116084070675255;
            x[22] = 0.192697580701371;
            x[23] = 0.268152185007254;
            x[24] = 0.341994090825758;
            x[25] = 0.413779204371605;
            x[26] = 0.483075801686179;
            x[27] = 0.549467125095128;
            x[28] = 0.61255388966798;
            x[29] = 0.67195668461418;
            x[30] = 0.727318255189927;
            x[31] = 0.77830565142652;
            x[32] = 0.824612230833312;
            x[33] = 0.865959503212259;
            x[34] = 0.902098806968874;
            x[35] = 0.932812808278677;
            x[36] = 0.957916819213792;
            x[37] = 0.977259949983775;
            x[38] = 0.990726238699457;
            x[39] = 0.998237709710559;
            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            w[0] = 0.0045212770985331;
            w[1] = 0.0104982845311527;
            w[2] = 0.0164210583819085;
            w[3] = 0.0222458491941663;
            w[4] = 0.0279370069800237;
            w[5] = 0.033460195282548;
            w[6] = 0.0387821679744707;
            w[7] = 0.0438709081856737;
            w[8] = 0.0486958076350726;
            w[9] = 0.0532278469839363;
            w[10] = 0.0574397690993923;
            w[11] = 0.0613062424929293;
            w[12] = 0.0648040134566006;
            w[13] = 0.0679120458152338;
            w[14] = 0.0706116473912864;
            w[15] = 0.0728865823958046;
            w[16] = 0.0747231690579682;
            w[17] = 0.0761103619006256;
            w[18] = 0.0770398181642474;
            w[19] = 0.077505947978425;
            w[20] = 0.0775059479784251;
            w[21] = 0.0770398181642484;
            w[22] = 0.0761103619006259;
            w[23] = 0.0747231690579689;
            w[24] = 0.0728865823958041;
            w[25] = 0.0706116473912865;
            w[26] = 0.0679120458152341;
            w[27] = 0.0648040134566013;
            w[28] = 0.0613062424929282;
            w[29] = 0.0574397690993913;
            w[30] = 0.0532278469839374;
            w[31] = 0.0486958076350719;
            w[32] = 0.0438709081856744;
            w[33] = 0.0387821679744719;
            w[34] = 0.0334601952825467;
            w[35] = 0.0279370069800232;
            w[36] = 0.022245849194167;
            w[37] = 0.0164210583819083;
            w[38] = 0.0104982845311531;
            w[39] = 0.00452127709853307;
        }

        if(n==50){
                x[0] = -0.998866404420071;
                x[1] = -0.994031969432091;
                x[2] = -0.985354084048006;
                x[3] = -0.972864385106692;
                x[4] = -0.956610955242808;
                x[5] = -0.936656618944878;
                x[6] = -0.913078556655792;
                x[7] = -0.885967979523614;
                x[8] = -0.855429769429946;
                x[9] = -0.821582070859336;
                x[10] = -0.784555832900399;
                x[11] = -0.744494302226069;
                x[12] = -0.701552468706822;
                x[13] = -0.655896465685439;
                x[14] = -0.60770292718495;
                x[15] = -0.55715830451465;
                x[16] = -0.504458144907464;
                x[17] = -0.449806334974039;
                x[18] = -0.393414311897565;
                x[19] = -0.335500245419437;
                x[20] = -0.276288193779532;
                x[21] = -0.216007236876042;
                x[22] = -0.154890589998146;
                x[23] = -0.0931747015600861;
                x[24] = -0.0310983383271889;
                x[25] = 0.0310983383271887;
                x[26] = 0.0931747015600863;
                x[27] = 0.154890589998146;
                x[28] = 0.216007236876042;
                x[29] = 0.276288193779532;
                x[30] = 0.335500245419437;
                x[31] = 0.393414311897565;
                x[32] = 0.449806334974039;
                x[33] = 0.504458144907464;
                x[34] = 0.55715830451465;
                x[35] = 0.60770292718495;
                x[36] = 0.655896465685439;
                x[37] = 0.701552468706822;
                x[38] = 0.744494302226069;
                x[39] = 0.784555832900399;
                x[40] = 0.821582070859336;
                x[41] = 0.855429769429946;
                x[42] = 0.885967979523613;
                x[43] = 0.913078556655792;
                x[44] = 0.936656618944878;
                x[45] = 0.956610955242808;
                x[46] = 0.972864385106692;
                x[47] = 0.985354084048006;
                x[48] = 0.994031969432091;
                x[49] = 0.998866404420071;
                //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                w[0] = 0.00290862255315515;
                w[1] = 0.00675979919574567;
                w[2] = 0.0105905483836499;
                w[3] = 0.0143808227614859;
                w[4] = 0.01811556071349;
                w[5] = 0.0217802431701243;
                w[6] = 0.0253606735700121;
                w[7] = 0.0288429935805348;
                w[8] = 0.0322137282235793;
                w[9] = 0.0354598356151453;
                w[10] = 0.0385687566125885;
                w[11] = 0.0415284630901479;
                w[12] = 0.0443275043388034;
                w[13] = 0.0469550513039485;
                w[14] = 0.0494009384494655;
                w[15] = 0.0516557030695818;
                w[16] = 0.053710621888996;
                w[17] = 0.0555577448062125;
                w[18] = 0.0571899256477287;
                w[19] = 0.0586008498132228;
                w[20] = 0.0597850587042651;
                w[21] = 0.0607379708417707;
                w[22] = 0.0614558995903172;
                w[23] = 0.0619360674206827;
                w[24] = 0.0621766166553468;
                w[25] = 0.0621766166553476;
                w[26] = 0.0619360674206826;
                w[27] = 0.0614558995903169;
                w[28] = 0.0607379708417701;
                w[29] = 0.0597850587042657;
                w[30] = 0.0586008498132221;
                w[31] = 0.0571899256477286;
                w[32] = 0.0555577448062128;
                w[33] = 0.0537106218889966;
                w[34] = 0.0516557030695815;
                w[35] = 0.0494009384494662;
                w[36] = 0.046955051303948;
                w[37] = 0.0443275043388033;
                w[38] = 0.0415284630901478;
                w[39] = 0.0385687566125883;
                w[40] = 0.0354598356151457;
                w[41] = 0.032213728223578;
                w[42] = 0.0288429935805348;
                w[43] = 0.0253606735700125;
                w[44] = 0.0217802431701249;
                w[45] = 0.0181155607134896;
                w[46] = 0.0143808227614852;
                w[47] = 0.0105905483836514;
                w[48] = 0.00675979919574515;
                w[49] = 0.0029086225531553;
        }
        if(n==100){
                            x[0] = -0.999713726773441;
                x[1] = -0.998491950639595;
                x[2] = -0.996295134733125;
                x[3] = -0.993124937037443;
                x[4] = -0.988984395242992;
                x[5] = -0.983877540706057;
                x[6] = -0.977809358486919;
                x[7] = -0.970785775763706;
                x[8] = -0.962813654255816;
                x[9] = -0.953900782925492;
                x[10] = -0.944055870136256;
                x[11] = -0.933288535043079;
                x[12] = -0.921609298145334;
                x[13] = -0.909029570982529;
                x[14] = -0.895561644970727;
                x[15] = -0.881218679385019;
                x[16] = -0.866014688497165;
                x[17] = -0.849964527879591;
                x[18] = -0.833083879888401;
                x[19] = -0.815389238339176;
                x[20] = -0.796897892390315;
                x[21] = -0.777627909649495;
                x[22] = -0.757598118519707;
                x[23] = -0.736828089802021;
                x[24] = -0.715338117573056;
                x[25] = -0.693149199355802;
                x[26] = -0.670283015603141;
                x[27] = -0.646761908514129;
                x[28] = -0.622608860203708;
                x[29] = -0.597847470247178;
                x[30] = -0.572501932621381;
                x[31] = -0.546597012065094;
                x[32] = -0.520158019881763;
                x[33] = -0.493210789208191;
                x[34] = -0.465781649773358;
                x[35] = -0.437897402172031;
                x[36] = -0.409585291678301;
                x[37] = -0.38087298162463;
                x[38] = -0.351788526372422;
                x[39] = -0.32236034390053;
                x[40] = -0.292617188038472;
                x[41] = -0.262588120371504;
                x[42] = -0.232302481844974;
                x[43] = -0.201789864095736;
                x[44] = -0.171080080538603;
                x[45] = -0.140203137236114;
                x[46] = -0.109189203580061;
                x[47] = -0.0780685828134361;
                x[48] = -0.0468716824215911;
                x[49] = -0.0156289844215426;
                x[50] = 0.0156289844215434;
                x[51] = 0.0468716824215919;
                x[52] = 0.0780685828134367;
                x[53] = 0.109189203580061;
                x[54] = 0.140203137236114;
                x[55] = 0.171080080538603;
                x[56] = 0.201789864095736;
                x[57] = 0.232302481844974;
                x[58] = 0.262588120371503;
                x[59] = 0.292617188038472;
                x[60] = 0.322360343900529;
                x[61] = 0.351788526372422;
                x[62] = 0.38087298162463;
                x[63] = 0.409585291678302;
                x[64] = 0.437897402172031;
                x[65] = 0.465781649773358;
                x[66] = 0.493210789208191;
                x[67] = 0.520158019881763;
                x[68] = 0.546597012065094;
                x[69] = 0.572501932621381;
                x[70] = 0.597847470247179;
                x[71] = 0.622608860203708;
                x[72] = 0.646761908514129;
                x[73] = 0.670283015603141;
                x[74] = 0.693149199355802;
                x[75] = 0.715338117573056;
                x[76] = 0.736828089802021;
                x[77] = 0.757598118519707;
                x[78] = 0.777627909649495;
                x[79] = 0.796897892390314;
                x[80] = 0.815389238339176;
                x[81] = 0.833083879888401;
                x[82] = 0.849964527879591;
                x[83] = 0.866014688497165;
                x[84] = 0.881218679385018;
                x[85] = 0.895561644970727;
                x[86] = 0.90902957098253;
                x[87] = 0.921609298145334;
                x[88] = 0.933288535043079;
                x[89] = 0.944055870136256;
                x[90] = 0.953900782925492;
                x[91] = 0.962813654255815;
                x[92] = 0.970785775763706;
                x[93] = 0.977809358486918;
                x[94] = 0.983877540706057;
                x[95] = 0.988984395242991;
                x[96] = 0.993124937037443;
                x[97] = 0.996295134733125;
                x[98] = 0.998491950639596;
                x[99] = 0.999713726773441;
                //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                w[0] = 0.000734634490507224;
                w[1] = 0.00170939265351756;
                w[2] = 0.00268392537155318;
                w[3] = 0.00365596120132672;
                w[4] = 0.00462445006342119;
                w[5] = 0.00558842800386482;
                w[6] = 0.00654694845084576;
                w[7] = 0.00749907325546491;
                w[8] = 0.00844387146966861;
                w[9] = 0.00938041965369488;
                w[10] = 0.010307802574869;
                w[11] = 0.0112251140231858;
                w[12] = 0.0121314576629799;
                w[13] = 0.0130259478929707;
                w[14] = 0.0139077107037196;
                w[15] = 0.0147758845274405;
                w[16] = 0.015629621077546;
                w[17] = 0.0164680861761457;
                w[18] = 0.0172904605683228;
                w[19] = 0.0180959407221288;
                w[20] = 0.0188837396133751;
                w[21] = 0.0196530874944352;
                w[22] = 0.0204032326462097;
                w[23] = 0.0211334421125273;
                w[24] = 0.0218430024162479;
                w[25] = 0.0225312202563362;
                w[26] = 0.0231974231852533;
                w[27] = 0.0238409602659688;
                w[28] = 0.024461202707957;
                w[29] = 0.0250575444815796;
                w[30] = 0.0256294029102089;
                w[31] = 0.0261762192395454;
                w[32] = 0.0266974591835706;
                w[33] = 0.0271926134465767;
                w[34] = 0.0276611982207931;
                w[35] = 0.0281027556591006;
                w[36] = 0.0285168543223952;
                w[37] = 0.0289030896011252;
                w[38] = 0.0292610841106382;
                w[39] = 0.0295904880599132;
                w[40] = 0.0298909795933333;
                w[41] = 0.0301622651051691;
                w[42] = 0.0304040795264541;
                w[43] = 0.0306161865839805;
                w[44] = 0.0307983790311516;
                w[45] = 0.0309504788504912;
                w[46] = 0.0310723374275672;
                w[47] = 0.0311638356962099;
                w[48] = 0.0312248842548502;
                w[49] = 0.0312554234538625;
                w[50] = 0.0312554234538631;
                w[51] = 0.0312248842548499;
                w[52] = 0.0311638356962098;
                w[53] = 0.0310723374275665;
                w[54] = 0.0309504788504895;
                w[55] = 0.0307983790311533;
                w[56] = 0.0306161865839805;
                w[57] = 0.0304040795264554;
                w[58] = 0.0301622651051681;
                w[59] = 0.0298909795933325;
                w[60] = 0.0295904880599135;
                w[61] = 0.0292610841106385;
                w[62] = 0.0289030896011247;
                w[63] = 0.0285168543223966;
                w[64] = 0.0281027556591018;
                w[65] = 0.0276611982207923;
                w[66] = 0.027192613446577;
                w[67] = 0.0266974591835712;
                w[68] = 0.0261762192395453;
                w[69] = 0.0256294029102076;
                w[70] = 0.0250575444815803;
                w[71] = 0.024461202707957;
                w[72] = 0.0238409602659677;
                w[73] = 0.0231974231852545;
                w[74] = 0.0225312202563367;
                w[75] = 0.0218430024162469;
                w[76] = 0.0211334421125267;
                w[77] = 0.0204032326462094;
                w[78] = 0.0196530874944353;
                w[79] = 0.0188837396133756;
                w[80] = 0.0180959407221278;
                w[81] = 0.0172904605683237;
                w[82] = 0.0164680861761444;
                w[83] = 0.015629621077546;
                w[84] = 0.0147758845274415;
                w[85] = 0.0139077107037189;
                w[86] = 0.0130259478929713;
                w[87] = 0.01213145766298;
                w[88] = 0.0112251140231865;
                w[89] = 0.0103078025748689;
                w[90] = 0.00938041965369423;
                w[91] = 0.00844387146966872;
                w[92] = 0.00749907325546535;
                w[93] = 0.00654694845084526;
                w[94] = 0.00558842800386609;
                w[95] = 0.00462445006342301;
                w[96] = 0.00365596120132592;
                w[97] = 0.00268392537155286;
                w[98] = 0.00170939265351822;
                w[99] = 0.000734634490505288;
        }

    }

    public double gau(double a, double b, IFunction1D func) {
        double res = 0.0;
        for (int i = 0; i < n; i++) {
            res += w[i] * func.calculate((a + b) / 2 + (b - a) / 2 * x[i]);
        }
        res *= (b - a) / 2.0;
        return res;
    }
    protected double ga(double a, double b, int N, IFunction1D func) {
        double res = 0.0;
        double h = (b-a)/(double)N;
        for (int i = 0; i < N; i++) {
            res+=gau(a+i*h, a+(i+1)*h, func);
        }
        return res;
    }
    public double Gauss(double a, double b, double eps, IFunction1D func){
        int N=1;
        double prev = ga(a, b, N, func);
        double next = ga(a, b, N * 2, func);
        while (Math.abs(prev - next) > eps){
            prev = next;
            N *= 2;
            next = ga(a, b, N * 2, func);
        }
        return next;
    }

    public double GaussOnGamma(Node A, Node B, IFunction2D func){
        double a,b;

        double res = 0.0;
        if(A.x==B.x){ // тоді по ігрику
            a = A.y; b = B.y;
            for (int i = 0; i < n; i++) {
                res += w[i] * func.calculate(A.x,(a + b) / 2 + (b - a) / 2 * x[i]) ;
            }
        }else{
            a = A.x; b = B.x;
            if(A.y==B.y){
                for (int i = 0; i < n; i++) {
                    res += w[i] * func.calculate((a + b) / 2 + (b - a) / 2 * x[i],A.y);
                }
            }else{
                double k = (B.y-A.y)/(A.x-B.x),
                       c = (B.y-A.y)/(A.x-B.x)*A.x + A.y ;
                for (int i = 0; i < n; i++) {
                    double xx = (a + b) / 2 + (b - a) / 2 * x[i];
                    res += w[i] * func.calculate(xx,k*xx+c);
                }
            }
        }
        res *= (b - a) / 2.0;

        return res;
    }

}
